package cn.demoncat.util.conn;

import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

import cn.demoncat.util.exception.IoRuntimeException;

/**
 * 连接池
 * 
 * @author 延晓磊
 *
 * @since 2019年11月4日
 */
public class ConnPool<T> extends GenericObjectPool<T>{

	/**
	 * 创建连接池
	 * 
	 * @param factory	连接工厂
	 * @param config	连接池配置
	 */
	public ConnPool(PooledObjectFactory<T> factory, GenericObjectPoolConfig<T> config) {
		super(factory, config);
	}
	
	/**
	 * 获取连接
	 * 
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年11月4日
	 */
	public T conn() {
		try {
			return borrowObject();
		} catch (Exception e) {
			throw new IoRuntimeException("获取连接失败", e);
		}
	}

	/**
	 * 返回连接（超过maxTotal仍未返回，再次获取时将阻塞等待）
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年11月4日
	 *
	 */
	public void close(T o) {
		if (o != null) {
			returnObject(o);
		}
	}
	
	/**
	 * 销毁连接(通常按照空闲原则自动销毁，不建议主动调用)
	 * 
	 * @param o
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年11月4日
	 */
	public void destroy(T o) {
		try {
			invalidateObject(o);
		} catch (Exception e) {
			// 销毁失败
		}
	}
 
	/**
	 * 获取连接 - 执行任务 - 关闭连接
	 * 
	 * @param task	连接任务
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年11月4日
	 */
	public <R>R execute(ConnTask<T,R> task) {
		// 获取连接
		T conn = conn();
		// 执行操作
		try {
			return task.execute(conn);
		} finally {
			// 返回连接
			close(conn);
		}
	}
	
}
